#  Copyright 2012 Eric Lawrey, Australian Institute of Marine Science
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.

#############################################
#       CALL R Functions in Cells           #
#############################################
# Any cells in the data frame that are strings and start with
# "R:" are interpretted as calls to R code. The remaining text
# in the cell is executed and the return value saved in the cell.
callRInCells <- function(dataFrame) {
  # Find and run any cells containing function calls to R.
  for (x in 1:ncol(dataFrame)) {
    for (y in 1:nrow(dataFrame)) {
      cell <- dataFrame[y,x]

      if (class(cell) == "character") {
        # Check if the cell contains a call to an R function as indicated by
        # starting with "R:"
        if (nchar(cell)>2 && substr(cell,1,2)=="R:") {
        
          # Get the R function call. Note: there is a limit of ~ 1000,000 characters
          Rtext <- substring(cell,3)
          #print(paste("Found in row:",y," col:", x," formula:",Rtext), sep="")
          # Save the result back in the dataFrame. Use a try catch to slightly improve
          # the error reporting.
          tryCatch(replaceVal <- eval(parse(text=Rtext)),
            error=function(e){
              stop(paste("Problem in cell row:",y," col:", x, "\n", e, sep=""))
            })
          #print(paste("Return string:",replaceVal))
          dataFrame[y,x] <- replaceVal
        }
      }
    }
  }

  return(dataFrame)
}